home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.02 Feb 89 / security code / MainDlog.Pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-11-29  |  7.9 KB  |  321 lines  |  [TEXT/MPS ]

  1. UNIT  MainDlog;
  2. {-------------------------------------------}
  3. (*
  4. ©1988 by Steve Seaquist. All rights reserved.
  5. Used by permission.  Use at your own risk.  
  6. No warranty is expressed or implied.  
  7.  
  8. This Macintosh virus-detecting program was 
  9. originally published and explained in the 
  10. February 1989 issue of MacTutor magazine.  
  11. Some aspects of its design are important to 
  12. security, and it uses some unusual 
  13. techniques, so please read the article.  
  14. *)
  15. {-------------------------------------------}
  16. INTERFACE
  17. USES
  18.   MacIntf,BitProcs,Globals;
  19.  
  20. PROCEDURE  InitMainDlog;
  21. FUNCTION   MainDlogWorkRequested
  22.   :          TMainItem;
  23.  
  24. {*******************************************}
  25. IMPLEMENTATION
  26. {$R-}
  27.  
  28. CONST
  29.   {--------item range--------}
  30.   kItemFst            = eDirs;
  31.   kItemLst            = eDBtn;
  32.   {----item type subranges---}
  33.   kBtnFst             = eDirs;
  34.   kBtnLst             = eQuit;
  35.   kChkFst             = eAwait;
  36.   kChkLst             = eTrace;
  37.   kStatFst            = eMain;
  38.   kStatLst            = eScOW;
  39.   kUItmFst            = eDBtn;
  40.   kUItmLst            = eDBtn;
  41.   {---titled item subrange---}
  42.   kTItmFst            = eDirs;
  43.   kTItmLst            = eScOW;
  44.  
  45. TYPE
  46.   TDitmPtr            = ^TDitmRec;
  47.   TDitmRec            =
  48.     PACKED RECORD
  49.     fProcPtr:         ProcPtr;
  50.     fRect:            Rect;
  51.     fType:            Byte;
  52.     fLen:             Byte;
  53.     fData:            INTEGER;
  54.     END;
  55.  
  56. VAR
  57.   gDBtnRect:          Rect;
  58.   gHdl:               ARRAY [eAwait..eTrace]
  59.                       OF ControlHandle;
  60.   gRect:              ARRAY [eAwait..eTrace]
  61.                       OF Rect;
  62.  
  63. {-------------------------------------------}
  64. PROCEDURE  ChkChk
  65.   (pItem:    TMainItem);
  66. BEGIN
  67. IF  (pItem < kChkFst)
  68. OR  (pItem > kChkLst) THEN
  69.   BEGIN
  70.   SysBeep(3);
  71.   EXIT(ChkChk);
  72.   END;
  73. SetCtlValue(gHdl[pItem],ORD(gOption[pItem]));
  74. IF  gDisabled[pItem] THEN
  75.   BEGIN
  76.   SetDItem(gDlogPtr,ORD(pItem),
  77.     ctrlItem+chkCtrl+itemDisable,
  78.     Handle(gHdl[pItem]),gRect[pItem]);
  79.   HiliteControl(gHdl[pItem],255);
  80.   END
  81. ELSE
  82.   BEGIN
  83.   SetDItem(gDlogPtr,ORD(pItem),
  84.     ctrlItem+chkCtrl,
  85.     Handle(gHdl[pItem]),gRect[pItem]);
  86.   HiliteControl(gHdl[pItem],0);
  87.   END;
  88. END;
  89. {-------------------------------------------}
  90. PROCEDURE  FrameDefaultBtn
  91.   (pWindowPtr:WindowPtr;
  92.   pItemNo:   INTEGER);
  93. VAR
  94.   sPenState: PenState;
  95. BEGIN
  96. GetPenState(sPenState);
  97. PenSize (3,3);
  98. FrameRoundRect(gDBtnRect,16,16);
  99. SetPenState(sPenState);
  100. END;
  101. {-------------------------------------------}
  102. PROCEDURE  InitMainDlog;
  103. CONST
  104.   kTitleMax       = 27;
  105.   kTItmLen        = 42;
  106.     { 14 + kTitleMax + ord(odd(kTitleMax)); }
  107.   kUItmLen        = 14;
  108. VAR
  109.   i:              TMainItem;
  110.   sDitmPtr:       TDitmPtr;
  111.   sDlogRect:      Rect;
  112.   sHdl:           Handle;
  113.   sNbrTItms:      INTEGER;
  114.   sNbrUItms:      INTEGER;
  115.   sRect:          ARRAY [eDirs..eScOW]
  116.                   OF Rect;
  117.   sSize:          Size;
  118.   sTitle:         ARRAY [eDirs..eScOW]
  119.                   OF STRING[kTitleMax];
  120.   sType:          INTEGER;
  121. BEGIN
  122. IF  gOption[eTrace] THEN
  123.   Trace('InitMainDlog');
  124. FOR i := kTItmFst TO kTItmLst DO
  125.   IF  (i >= kBtnFst)
  126.   AND (i <= kBtnLst) THEN
  127.     BEGIN
  128.     SetRect   (sRect[i], 266, 65, 346, 83);
  129.     OffsetRect(sRect[i],0,
  130.               27*(ORD(i)-ORD(kBtnFst)));
  131.     END
  132.   ELSE IF (i >= kChkFst)
  133.   AND     (i <= kChkLst) THEN
  134.     BEGIN
  135.     SetRect   (sRect[i],  24, 62, 185, 80);
  136.     OffsetRect(sRect[i],0,
  137.               20*(ORD(i)-ORD(kChkFst)));
  138.     END
  139.   ELSE
  140.     SetRect   (sRect[i],  12, 42, 216, 60);
  141. OffsetRect(sRect[eMain], 080,-30);
  142. OffsetRect(sRect[eOpts], 000,000);
  143. OffsetRect(sRect[eScOW], 216,000);
  144.  
  145. gDBtnRect := sRect[kItemFst];
  146. InsetRect (gDBtnRect, -4, -4);
  147.  
  148. WITH sDlogRect, gSFGetPt DO
  149.   BEGIN
  150.   top    := v - 10;
  151.   left   := h - 10;
  152.   bottom := top  + 210;
  153.   right  := left + 368;
  154.   END;
  155.  
  156. sTitle[eDirs]  := 'Directories';
  157. sTitle[eDiry]  := 'Directory';
  158. sTitle[eEvery] := 'Everything';
  159. sTitle[eFiles] := 'Files';
  160. sTitle[eQuit]  := 'Quit';
  161. sTitle[eAwait] := 'Await Keypress';
  162. sTitle[eBeeps] := 'Beep';
  163. sTitle[eFgPr]  := 'Fingerprint';
  164. sTitle[eFgPrC] := 'Fingerprint CODEs';
  165. sTitle[eLList] := 'Long Listing';
  166. sTitle[eRmVir] := 'Remove Viruses';
  167. sTitle[eTrace] := 'Trace';
  168. sTitle[eMain]  := 
  169.   'Security Patrol Main Dialog';
  170. sTitle[eOpts]  := 'Options:';
  171. sTitle[eScOW]  := 'Scope Of Work:';
  172.  
  173. sNbrTItms := (ORD(kTItmLst)-ORD(kTItmFst))+1;
  174. sNbrUItms := (ORD(kUItmLst)-ORD(kUItmFst))+1;
  175. sHdl := NewHandle(2 + (sNbrTItms*kTItmLen)
  176.                     + (sNbrUItms*kUItmLen));
  177. TWordPtr(sHdl^)^ := ORD(kItemLst) - 1;
  178. sSize := 2;
  179. FOR i := kItemFst TO kItemLst DO
  180.   BEGIN
  181.   IF  gOption[eTrace] THEN
  182.     TraceNbr('sSize = ',sSize);
  183.   sDitmPtr := POINTER(ORD4(sHdl^)+sSize);
  184.   WITH sDitmPtr^ DO
  185.     IF  (i >= kTItmFst)
  186.     AND (i <= kTItmLst) THEN
  187.       BEGIN
  188.       fProcPtr := NIL;
  189.       fRect    := sRect[i];
  190.       IF  (i <= kBtnLst) THEN
  191.         fType  := ctrlItem + btnCtrl
  192.       ELSE IF  (i <= kChkLst) THEN
  193.         fType  := ctrlItem + chkCtrl
  194.       ELSE
  195.         fType  := statText + itemDisable;
  196.       BlockMove(@sTitle[i],@fLen,
  197.                 LENGTH(sTitle[i])+1);
  198.       sSize := sSize+14+fLen+ORD(ODD(fLen));
  199.       END
  200.     ELSE IF  (i = eDBtn) THEN
  201.       BEGIN
  202.       fProcPtr := @FrameDefaultBtn;
  203.       fRect    := gDBtnRect;
  204.       fType    := userItem + itemDisable;
  205.       fLen     := 0;
  206.       sSize    := sSize + 14;
  207.       END
  208.     ELSE
  209.       SysBeep(60);
  210.   END;
  211. SetHandleSize(sHdl,sSize);
  212. gDlogPtr := NewDialog(NIL,sDlogRect,'',
  213.   FALSE,dBoxProc,POINTER(-1),FALSE,0,sHdl);
  214. FOR i := kChkFst TO kChkLst DO
  215.   BEGIN
  216.   GetDItem(gDlogPtr,ORD(i),sType,
  217.            Handle(gHdl[i]),gRect[i]);
  218.   IF  gOption[eTrace] THEN
  219.     TraceNbr('ChkChk’ing item ',ORD(i));
  220.   ChkChk(i);
  221.   END;
  222. END;
  223. {-------------------------------------------}
  224. FUNCTION   KybdEquivsFilter
  225.   (pDialogPtr:   DialogPtr;
  226.   VAR pEventRec: EventRecord;
  227.   VAR pItemHit:  INTEGER)
  228.   :              BOOLEAN;
  229. VAR
  230.   sChar:
  231.     RECORD
  232.     CASE INTEGER OF
  233.     0:(F1,F2,F3: SignedByte;
  234.        Enum:     TMainItem);
  235.     1:(L:        LONGINT);
  236.     END;
  237.   sItem:         TMainItem;
  238. BEGIN
  239. sItem := eNotADlogItem;
  240. WITH pEventRec DO
  241.   IF  (what = keyDown) THEN
  242.     BEGIN
  243.     sChar.L := BAnd(message,charCodeMask);
  244.     IF  (sChar.L = $03) 
  245.     OR  (sChar.L = $0D) THEN
  246.       sItem := eDirs
  247.     ELSE IF (sChar.L = ORD('D')) 
  248.     OR      (sChar.L = ORD('d')) THEN
  249.       sItem := eDiry
  250.     ELSE IF (sChar.L = ORD('E')) 
  251.     OR      (sChar.L = ORD('e')) THEN
  252.       sItem := eEvery
  253.     ELSE IF (sChar.L = ORD('F')) 
  254.     OR      (sChar.L = ORD('f')) THEN
  255.       sItem := eFiles
  256.     ELSE IF (sChar.L = ORD('Q')) 
  257.     OR      (sChar.L = ORD('q')) 
  258.     OR ((BAnd(modifiers,cmdKey)<>0) 
  259.         AND (sChar.L = ORD('.'))) THEN
  260.       sItem := eQuit
  261.     ELSE
  262.       BEGIN
  263.       sChar.L := 
  264.         (sChar.L-ORD4('1')) + ORD(kChkFst);
  265.       IF  (sChar.L >= ORD(kChkFst)) 
  266.       AND (sChar.L <= ORD(kChkLst)) THEN
  267.         IF  NOT(gDisabled[sChar.Enum]) THEN
  268.           sItem := sChar.Enum;
  269.       END;
  270.     END;
  271. IF  (sItem = eNotADlogItem) THEN
  272.   KybdEquivsFilter := FALSE
  273. ELSE
  274.   BEGIN
  275.   pItemHit         := ORD(sItem);
  276.   KybdEquivsFilter := TRUE;
  277.   END;
  278. END;
  279. {-------------------------------------------}
  280. FUNCTION   MainDlogWorkRequested
  281.   :          TMainItem;
  282. VAR
  283.   sItem:
  284.     RECORD
  285.     CASE INTEGER OF
  286.     0:(Filler: SignedByte;
  287.        Enum:   TMainItem);
  288.     1:(Int:    INTEGER);
  289.     END;
  290. BEGIN
  291. IF  gOption[eTrace] THEN
  292.   Trace('MainDlogWorkRequested');
  293. BringToFront(gDlogPtr);
  294. ShowWindow  (gDlogPtr);
  295. ModalDialog (@KybdEquivsFilter,sItem.Int);
  296. WHILE (sItem.Enum >= kChkFst)
  297. AND   (sItem.Enum <= kChkLst) DO
  298.   BEGIN
  299.   gOption[sItem.Enum] := 
  300.     NOT(gOption[sItem.Enum]);
  301.   ChkChk(sItem.Enum);
  302.   IF  (sItem.Enum = eFgPr) THEN
  303.     BEGIN
  304.     gDisabled[eFgPrC] := NOT(gOption[eFgPr]);
  305.     gOption  [eFgPrC] := FALSE;
  306.     ChkChk(eFgPrC);
  307.     END;
  308.   ModalDialog (@KybdEquivsFilter,sItem.Int);
  309.   END;
  310. HideWindow  (gDlogPtr);
  311. SetPort     (gGrafPtr);
  312. IF  gOption[eTrace] THEN
  313.   TraceNbr('Returning ',ORD(sItem.Enum));
  314. IF  (sItem.Enum >= kItemFst)
  315. AND (sItem.Enum <= kItemLst) THEN
  316.   MainDlogWorkRequested := sItem.Enum
  317. ELSE
  318.   MainDlogWorkRequested := eQuit;
  319. END;
  320. {*******************************************}
  321. END.